package main

import (
	"asynccache/asynccache"
	"fmt"
	"log"
	"time"
)

// 模拟一个简单的数据获取函数
func simpleFetcher(key string) (interface{}, error) {
	log.Printf("Fetching data for key: %s\n", key)
	time.Sleep(500 * time.Millisecond) // 模拟数据获取的延迟
	return fmt.Sprintf("value_for_%s", key), nil
}

// 打印缓存中所有的数据观察
func showAllCacheData(cache asynccache.AsyncCache) {
	cacheData := cache.Dump() // 导出cache数据
	// cacheData map[string]interface{} 类型为interface{}，代表任意类型
	for k, v := range cacheData {
		// %s代表匹配字符串，%+v代表构造任意类型
		log.Printf("Fetching data for key: %s, value: %+v", k, v)
	}
}

func main() {
	// 创建一个 AsyncCache 实例
	cache := asynccache.NewAsyncCache(asynccache.Options{
		RefreshDuration: 2 * time.Second, // 每2秒刷新一次
		Fetcher:         simpleFetcher,
		EnableExpire:    true,
		ExpireDuration:  5 * time.Second, // 每5秒过期一次
		ErrorHandler: func(key string, err error) {
			log.Printf("Error fetching key %s: %v\n", key, err)
		},
		ChangeHandler: func(key string, oldData, newData interface{}) {
			log.Printf("Key %s changed from %v to %v\n", key, oldData, newData)
		},
		DeleteHandler: func(key string, oldData interface{}) {
			log.Printf("Key %s expired with value %v\n", key, oldData)
		},
	})

	// 设置默认值
	cache.SetDefault("key1", "default_value_for_key1")

	// 观察缓存数据
	showAllCacheData(cache)

	// 获取值
	val, err := cache.Get("key1")
	if err != nil {
		log.Printf("Error getting key1: %v\n", err)
	} else {
		log.Printf("Got value for key1: %v\n", val)
	}

	// 使用 GetOrSet
	val = cache.GetOrSet("key2", "default_value_for_key2")
	log.Printf("Got value for key2: %v\n", val)

	// 等待刷新和过期
	time.Sleep(6 * time.Second)

	// 再次获取值
	val, err = cache.Get("key1")
	if err != nil {
		log.Printf("Error getting key1 after refresh: %v\n", err)
	} else {
		log.Printf("Got value for key1 after refresh: %v\n", val)
	}

	// 删除特定的缓存项
	cache.DeleteIf(func(key string) bool {
		return key == "key2"
	})

	// 关闭缓存
	cache.Close()

	// 尝试获取值，应该会失败
	val, err = cache.Get("key1")
	if err != nil {
		log.Printf("Error getting key1 after close: %v\n", err)
	} else {
		log.Printf("Got value for key1 after close: %v\n", val)
	}
}
